#pragma once

#include "cLua/cLua.h"
#include "lua_rover/lua_rover.hpp"
#include <boost/function.hpp>
#include <string>
#include <vector>
#include <hash_map>

namespace umtl
{
	//////////////////////////////////////////////////////////////////////////
	// 

	class Lua : public cLua
	{
	private:
		
		struct GetStringArgumentFunctor;
		template<class T> struct GetNumberArgumentFunctor;
		struct PushStringToStack;
		struct PushNumberToStack;


	public:

		Lua() {}
		virtual ~Lua() {}

		template<typename T>
		T GetArgument(const char* lua_name, int argNum);

		template<typename T>
		void PushArgument(const char* lua_name, T data);

		template<typename T>
		T ReadFromLua(const char* file_name, std::string element_name);

		template<typename T>
		void WriteToLua(const char* file_name, std::string element_name, T& data);


	private:

		struct GetStringArgumentFunctor
		{
			char* operator()(const char* lua_name, Lua*owner, int argNum)
			{
				return const_cast<char*>( owner->GetStringArgument(lua_name, argNum) );
			}
		};

		template<class T>
		struct GetNumberArgumentFunctor
		{
			T operator()(const char* lua_name, Lua* owner, int argNum)
			{
				return static_cast<T>(owner->GetNumberArgument(lua_name, argNum));
			}
		};

		struct PushStringToStack
		{
			void operator()(const char* lua_name, Lua* owner, std::string arg)
			{
				owner->PushString(lua_name, arg.c_str());
			}
		};

		struct PushNumberToStack
		{
			void operator()(const char* lua_name, Lua* owner, double arg)
			{
				owner->PushNumber(lua_name, arg);
			}
		};
	};

	Lua& GetLua();

	//////////////////////////////////////////////////////////////////////////
}

#include "Lua.hpp"

